1 package tw.com.javaworld.CH11;
2 
3 import java.io.*;
4 import javax.servlet.*;
5 import javax.servlet.http.*;
6 import java.util.zip.GZIPOutputStream;
7 
8 public class GZIPEncodeFilter implements Filter {
9     
10    public void init(FilterConfig filterConfig) {
11    }
12    
13    public void doFilter(
14        ServletRequest request,
15        ServletResponse response,
16        FilterChain chain)
17        throws IOException, ServletException {
18        String transferEncoding = getGZIPEncoding((HttpServletRequest) request);
19        if (transferEncoding == null) {
20            chain.doFilter(request, response);
21        } else {
22            ((HttpServletResponse) response).setHeader(
23                "Content-Encoding",
24                transferEncoding);
25            GZIPEncodableResponse wrappedResponse =
26                new GZIPEncodableResponse((HttpServletResponse) response);
27            chain.doFilter(request, wrappedResponse);
28            wrappedResponse.flush();
29        }
30    }
31    
32    public void destroy() {
33    }
34    
35    private static String getGZIPEncoding(HttpServletRequest request) {
36        String acceptEncoding = request.getHeader("Accept-Encoding");
37        if (acceptEncoding == null)
38            return null;
39        acceptEncoding = acceptEncoding.toLowerCase();
40        if (acceptEncoding.indexOf("x-gzip") >= 0) {
41            return "x-gzip";
42        }
43        if (acceptEncoding.indexOf("gzip") >= 0) {
44            return "gzip";
45        }
46        return null;
47    }
48    
49    private class GZIPEncodableResponse extends HttpServletResponseWrapper {
50        private GZIPServletStream wrappedOut;
51        public GZIPEncodableResponse(HttpServletResponse response)
52            throws IOException {
53            super(response);
54            wrappedOut = new GZIPServletStream(response.getOutputStream());
55        }
56        public ServletOutputStream getOutputStream() throws IOException {
57            return wrappedOut;
58        }
59        private PrintWriter wrappedWriter;
60        public PrintWriter getWriter() throws IOException {
61            if (wrappedWriter == null) {
62                wrappedWriter =
63                    new PrintWriter(
64                        new OutputStreamWriter(
65                            getOutputStream(),
66                            getCharacterEncoding()));
67            }
68            return wrappedWriter;
69        }
70        public void flush() throws IOException {
71            if (wrappedWriter != null) {
72                wrappedWriter.flush();
73            }
74            wrappedOut.finish();
75        }
76    }
77    
78    private class GZIPServletStream extends ServletOutputStream {
79        private GZIPOutputStream outputStream;
80        public GZIPServletStream(OutputStream source) throws IOException {
81            outputStream = new GZIPOutputStream(source);
82        }
83        public void finish() throws IOException {
84            outputStream.finish();
85        }
86        public void write(byte[] buf) throws IOException {
87            outputStream.write(buf);
88        }
89        public void write(byte[] buf, int off, int len) throws IOException {
90            outputStream.write(buf, off, len);
91        }
92        public void write(int c) throws IOException {
93            outputStream.write(c);
94        }
95        public void flush() throws IOException {
96            outputStream.flush();
97        }
98        public void close() throws IOException {
99            outputStream.close();
00        }
01    }
02}